package runnable_functions;



import gui.Main;

import java.sql.SQLException;
import java.util.concurrent.CountDownLatch;


import details.*;



/**
 * @author Tami
 *
 */
public class USERfunctions extends RunnableClasses implements Constant_definitions {
	
	
	public USERfunctions(){}
	
	public  User log_in_user(String userName,String password){
		User user = null;
		try{
			int check = isRegisteredUser(userName);
			if(check == YES){
				System.out.println("is registered");
				check = isUsersPassword(userName,password);
				if(check==NO){
					System.out.println("not user-names's password");
					Main.guiInt.notifyGeneralError("not user-names's password");
				}
			
			
				else{
					System.out.println("is user-names's password");
					user = Main.db.findUser(userName);
					Main.guiInt.notifySuccess();
					Main.guiInt.setUser(user);
					
				}
			
			}
			else {
				Main.guiInt.notifyGeneralError("not registered username");
			}
		}
		catch(SQLException e){
			Main.guiInt.notifyDBFailure(e.getMessage());
		}
		
		return user;
	}
	
	public  User addNewUser(String userName, String pass){
		boolean check = checkUserNameLegality(userName);
		//int flag = OK;
		User user = null;
		int user_id=0;
		if(check == LEGAL){
			try{ 
				check = checkUserNameValidity(userName);
				if(check == USED){
					
					Main.guiInt.notifyGeneralError("these user-name is already in use");
				}
				else {
					check = checkPasswordLegality(pass);
					if(check==LEGAL){
						try{
							user_id=Main.db.addUser(userName, pass);
							user = new User(user_id,userName,pass);
							
						}
						catch(SQLException e){
							
							Main.guiInt.notifyDBFailure(e.getMessage());
						}
					}
					else {
						
						Main.guiInt.notifyGeneralError("illegal password, need to be 8 chars of type : A-Z,a-z,0-9");
					}
				}
			}
			catch(SQLException e){
				
				Main.guiInt.notifyDBFailure(e.getMessage());
			}
		}
		else {
			
			Main.guiInt.notifyGeneralError("illegal username");
		}
			
		
		return user;
	}
	
	public  int deleteUser(String userName, String pass) {
		int flag = OK;
		try{
			int check = isRegisteredUser(userName);
			if(check == YES){
				check = isUsersPassword(userName,pass);
				if(check==YES){
					try{
						Main.db.deleteUser(userName);
					}
					catch(SQLException e){
						flag = FAILED;
						Main.guiInt.notifyDBFailure(e.getMessage());
					}
				}
				else {
					flag = FAILED;
					Main.guiInt.notifyGeneralError("not user-names's password");
				}
			}
			else {
				flag = FAILED;
				Main.guiInt.notifyGeneralError("not registered username");
			}
		}
		catch(SQLException e){
			flag = FAILED;
			Main.guiInt.notifyDBFailure(e.getMessage());
		}
		
		return flag;
	}
	
	public  int changePassword(String userName, String oldPass, String newPass){
		int flag = OK;
		try{
		int check = isRegisteredUser(userName);
		if(check == YES){
			System.out.println("is registered");
			check = isUsersPassword(userName,oldPass);
			if(check==YES){
				boolean legal = checkPasswordLegality(newPass);
				if(legal==LEGAL){
					try{
						Main.db.changePass(userName, newPass);/* TODO: have to assure that the pass wont change if error has occured*/
					}
					catch(SQLException e){
						flag = FAILED;
						throw e;
					}
				}
				else {
					flag = FAILED;
					Main.guiInt.notifyGeneralError("not legal password");
				}
			}
			else {
				flag = FAILED;
				Main.guiInt.notifyGeneralError("not user-names's password");
			}
		}
		else {
			flag = FAILED;
			Main.guiInt.notifyGeneralError("not registered username");
		}
		}
		catch(SQLException e){
			flag = FAILED;
			Main.guiInt.notifyDBFailure(e.getMessage());
		}
		
		return flag;
	}

	/* checks if this user-name is used or free ( when the new user wants to register*/
	public  boolean checkUserNameValidity(String userName) throws SQLException{
		boolean flag = VALID;
		if(isRegisteredUser(userName)==YES){
				flag = USED;
			}

		return flag;
	}

	/* has to be up to 15 chars of English low or upper letters or numbers: 0-9 or '.' and'_'*/
	public  boolean checkUserNameLegality(String userName){
		if(userName.length() >15 || userName.length()==0)
			return WRONG;
		for(int i = 0;i<userName.length();i++){//!!!
			if((userName.charAt(i)<'.')||(userName.charAt(i) > '.' && userName.charAt(i) < '0')||(userName.charAt(i) > '9' && userName.charAt(i) < 'A') || (userName.charAt(i) >'Z' && userName.charAt(i) < '_')||(userName.charAt(i) >'_' && userName.charAt(i) < 'a') || (userName.charAt(i) >'z')){
				return WRONG;
			}
		}
		return LEGAL;
	}

	/* verifies that the password consists of  8 characters of English low or upper letters and numbers: 0-9*/
	public  boolean checkPasswordLegality(String password) {
		if(password.length() != 8 ){
			return WRONG;
		}
		for(int i = 0;i<password.length();i++){//!!!
			if((password.charAt(i)<'0')||(password.charAt(i) > '9' && password.charAt(i) < 'A') || (password.charAt(i) >'Z' && password.charAt(i) < 'a') || (password.charAt(i) >'z')){
				return WRONG;
			}
		}
		return LEGAL; 
	}

	/*checks if the following password belongs to the following users */
	public  int isUsersPassword(String username, String password) throws SQLException{
		int flag = NO;
		String pass;
		pass = getUserPassword(username);
		if(pass.compareTo(password)==0){
			flag=YES;
		}	
		System.out.println("flag is "+flag);
		return flag;
	}

	/*checks if the following user is registered already*/
	public  int isRegisteredUser(String username) throws SQLException{
		int flag = NO;
		User user = Main.db.findUser(username);
			if(user!=null ){
				flag=YES;
			}
		
		return flag;
	}

	
	public String getUserPassword(String username) throws SQLException{
		String pass = null;
		User user = Main.db.findUser(username);
			if(user!=null){
				pass = user.getPassword();
			}
		System.out.println("pass from db"+pass);
		return pass;
	}

	
/**************** RUNNABLE CLASSES**********************/
	
	
public class LogInUser implements Runnable{
		
		private String user_name;
		private String password;
		private CountDownLatch startSignal;
		//private CountDownLatch startSignal1;

		public LogInUser(String user_name,String password,CountDownLatch startSignal){
			this.user_name = user_name;
			this.password = password;
			this.startSignal = startSignal;
			//this.startSignal1 = startSignal1;
		}
		public void run() {
			
			
			Main.db.openConnection();
			log_in_user(user_name,password);
			
			Main.db.closeConnection();
			startSignal.countDown();	
		}
}

	
	
	


	public class MakeNewUser implements Runnable{
		
		private String user_name;
		private String password;
		private CountDownLatch startSignal;

		public MakeNewUser(String user_name,String password, CountDownLatch startSignal){
			this.user_name = user_name;
			this.password = password;
			this.startSignal = startSignal;
		}
		public void run() {
			//int result = FAILED;
			User user;
			Main.db.openConnection();
			user = addNewUser(user_name,password);
			
			if (user !=null){
				Main.guiInt.setUser(user);
				Main.guiInt.notifySuccess();
				}
				
			
			Main.db.closeConnection();
			startSignal.countDown();
				
		}
	
	
		
	}
	


	
	
	
	public class DeleteUser implements Runnable{
		
		private String user_name;
		private String password;
		private User user;
		private CountDownLatch startSignal;

		public DeleteUser(String user_name,String password,User curr_user, CountDownLatch startSignal){
			this.user_name = user_name;
			this.password = password;
			this.user = curr_user;
			this.startSignal = startSignal;
		}
		public void run() {
			
			if(user.getUserName().equals(User.getAdmin()) || user.getUserName().equals(user_name)){
				
			
			int result = FAILED;
			
			Main.db.openConnection();
			result = deleteUser(user_name,password);
			if (result == OK){
				Main.guiInt.notifySuccess();
			}
			}
			else{
				Main.guiInt.notifyGeneralError("dont have permission to delete other users");
			}
			Main.db.closeConnection();
			startSignal.countDown();
				
		}
	}
	
	
public class ChangePassword implements Runnable{
		
		private String user_name;
		private String oldPassword;
		private String newPassword;
		private CountDownLatch startSignal;

		public ChangePassword(String user_name,String oldPassword,String newPassword,CountDownLatch startSignal){
			this.user_name = user_name;
			this.oldPassword = oldPassword;
			this.newPassword = newPassword;
			this.startSignal = startSignal;
		}
		public void run() {
			
			int result = FAILED;
			Main.db.openConnection();
			result = changePassword(user_name,oldPassword,newPassword);
			if (result == OK){
				Main.guiInt.notifySuccess();
				
			}
			Main.db.closeConnection();
			startSignal.countDown();	
				
		}
	}

	
	
	

}
